from django.http import JsonResponse
from urllib.parse import quote
from random import randint
from django.core.cache import cache

# 得到一个8位随机值
def get_state():
    res = ""
    for i in range(8):
        res += str(randint(0, 9))
    return res

def apply_code(request):
    appid = "3006"
    # 这里需要使用quote将网址中的特殊字符进行重新编码，防止在后续解析过程中出bug
    redirect_uri = quote("https://app3006.acapp.acwing.com.cn/settings/acwing/web/receive_code/")
    scope = "userinfo"
    state = get_state()
    # 将state存入我们的radius数据库中，有效期为2h
    '''
    state的作用是防止CSRF攻击
    CSRF：Cross-site request forgery，跨站请求伪造
    本来只有AcWing能够返回授权码code，但是如果别的恶意网站也向我们发送code，
    此时我们就需要结合state来进行验证
    只有返回的state和发出去的state一致，我们才能够认为这个code是合法的
    至于其安全性，我们的state是一个8位的随机数
    这样的话，恶意网站要想伪造一个合法的state，需要进行8^10次尝试
    可以视为不可能
    且我们state的有效期也只有2h
    '''
    cache.set(state, True, 7200)

    '''
    apply_code_url是重定向的网址，搭配game/static/js/src/settings/zbase.js使用
    使用时会将网址重定向到apply_code_url，申请用户的授权许可，
    并将state传入，以便在后续的receive_code函数中进行验证
    若用户同意授权，根据redirect_uri提供的地址，
    AcWing会将code和state传回我们自己的服务器，
    然后服务器将code和state传回给receive_code函数
    接下来在receive_code函数中进行后续说明
    '''
    apply_code_url = "https://www.acwing.com/third_party/api/oauth2/web/authorize/"
    return JsonResponse({
        'result': "success",
        'apply_code_url': apply_code_url + "?appid=%s&redirect_uri=%s&scope=%s&state=%s" % (appid, redirect_uri, scope, state)
    })

